package com.example.payment.service.impl;

import com.alipay.api.AlipayApiException;
import com.example.core.exception.HotelException;
import com.example.model.check_in.CheckIn;

import com.example.model.payment.Payment;
import com.example.model.payment.PaymentResultVo;
import com.example.core.utils.ParamParser;

import com.example.payment.mapper.PaymentMapper;
import com.example.payment.service.PaymentService;
import com.example.payment.strategy.PayTypeStrategy;
import com.example.payment.strategy.StrategyFactory;
import com.example.redis.utils.CacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.example.model.constants.CodeConstants.PAY_LESS;
import static com.example.model.constants.KeyConstants.KEY_ZFB_PAY;

@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private CacheUtil cacheUtil;

    @Autowired
    private StrategyFactory strategyFactory;

    private Payment payment;

    @Override
    public PaymentResultVo makePayment(Payment payment, BigDecimal amount, BigDecimal pay) {
        this.payment = payment;
        if (amount.compareTo(pay) > 0) {
            throw new HotelException(PAY_LESS, "支付金额小于订单金额");
        }
        PayTypeStrategy strategy = strategyFactory.getStrategy(payment.getPaymentType());
        PaymentResultVo paymentResultVo;
        try {
            paymentResultVo = strategy.pay(payment, amount, pay);
            if (payment.getPaymentType().equals("Cash")) {
                insert(payment);
            }
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        return paymentResultVo;
    }

    @Override
    public int insert(Payment payment) {
        return paymentMapper.insert(payment);
    }

    @Override
    public void analysis(String notifyData) {
        Map<String, String> parseParam = ParamParser.parseParam(notifyData);
        if (parseParam.get("refund_fee") != null) {
            update(parseParam.get("trade_no"));
        } else {
            this.payment.setTradeNo(parseParam.get("trade_no"));
            this.payment.setBuyerId(parseParam.get("buyer_id"));
            this.payment.setPaymentDate(LocalDateTime.now());
            insert(this.payment);
            cacheUtil.setObject(KEY_ZFB_PAY + this.payment.getPaymentId(), this.payment, 5);
        }


    }

    @Override
    public Boolean research(Long paymentId) {
        return cacheUtil.getObject(KEY_ZFB_PAY + paymentId) != null;
    }

    @Override
    public Payment get(Long paymentId) {
        return paymentMapper.get(paymentId);
    }

    @Override
    public void refund(Long paymentId, BigDecimal amount) throws AlipayApiException {
        PayTypeStrategy strategy = strategyFactory.getStrategy("zfb");
        strategy.refund(paymentId, amount);
    }

    @Override
    public int update(String tradeNo) {
        return paymentMapper.update(tradeNo);
}

    @Override
    public List<Payment> list(Payment payment) {
        return paymentMapper.list(payment);
    }
}
